#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
Ce module contient plusieurs classes permettant de gérer les éléments 
principaux d'un jeu de blackjack: la carte avec sa valeur, une donne
et sa valeur, ainsi qu'un paquet standard de 52 cartes.
"""
__auteur__ = ""
__coequipiers__ = None
__date__ = ""

import JeuDeCarte

class Carte(JeuDeCarte.Carte):
    """ Cette classe encapsule une carte de blackjack. Elle ajoute 
    à sa classe de base une valeur spécifique à chaque figure. """
    valeurs = {'A': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8,
               '9': 9, '10': 10, 'J': 10, 'Q': 10, 'K': 10}

    def valeur(self):
        """ Calculer la valeur de la carte. 

        :returns: la valeur nominale de la carte pour les cartes de '2' à '10',
        10 pour les figures ('J', 'Q' et 'K'), et 1 pour les aces.
        """
        if self.face_visible:
            return Carte.valeurs[self.figure] 
        else:
            return None

class Donne(JeuDeCarte.Donne):
    """ Cette classe encapsule une donne de blackjack. ELle ajoute
    à sa classe de base la capacité de calculer la valeur totale de
    la donne. """

    def valeur(self):
        """ Calculer la valeur totale de la donne.

        :returns: la valeur de la donne à condition que toutes les faces soient 
        visibles; autrement None. Si la donne contient un ace, on ajoute 10 à sa 
        valeur, à condition que le résultat soit inférieur ou égal à 21.
        """
        # si une carte est cachée, retourner None
        for carte in self.cartes:
            if not carte.valeur():
                return None
        # additionner la valeur des cartes en comptant les aces pour 1
        somme = 0
        ace = False
        for carte in self.cartes:
            if carte.figure == 'A':
                ace = True
            somme += carte.valeur()
        # s'il y a un ace dans la donne, ajouter 10 à la valeur si le total 
        # est inférieur ou égal à 21
        if ace and somme < 12: 
            somme += 10
        # retourner la valeur totale
        return somme

class Joueur(Donne):
    """ Cette classe encapsule un joueur en ajoutant simplement un nom
    de joueur à une donne de blackjack.
    """

    def __init__(self, nom):
        """ Construire un joueur de blackjack.

        :param nom: le nom du joueur.
        :returns: rien.
        """
        super().__init__()
        self.nom = nom

    def __str__(self):
        """ Convertir en chaîne de caractères.

        :returns: une chaîne de caractère sous la forme «nom: donne».
        """
        valeur = self.valeur() if self.valeur() else '??'
        return '{:>8} = {:2} ({})'.format(super().__str__(), valeur, self.nom)

    def carter(self):
        """ Prendre la décision de tirer ou non une carte. """
        reponse = str.lower(input('Voulez-vous tirer une carte (o/n)? '))
        if reponse == 'o':
            return True
        elif reponse == 'n':
            return False
        else:
            print('réponse invalide!')
            return self.carter()

class Croupier(Joueur):
    """ Cette classe encapsule un croupier en spécialisant le comportement
    du joueur; le croupier est obligé de tirer une carte tant que la valeur 
    sa donne est inférieure à 17. """

    def __init__(self):
        """ Construire un croupier de blackjac en le nommant «Le croupier».

        :returns: rien.
        """
        super().__init__(nom='Le croupier')

    def carter(self):
        """ Prendre la décision de tirer ou non une carte. 

        :returns: True lorsque la valeur de sa donne est inférieure à 17;
        False autrement.
        """
        if self.valeur() and self.valeur() < 17:
            return True
        else:
            return False

if __name__ == '__main__':
    # programme principal
    print("Le module Blackjack n'est pas conçu pour être exécuté en tant que programme principal")
